package com.fingard.dsp.bank.directbank.cmb02;

import java.io.File;
import java.util.Date;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.dsp.bank.directbank.cmb02.util.CDesHelper;
import com.fingard.io.FileHelper;
import com.fingard.net.ITcpClient;
import com.fingard.net.TcpPortClient;
import com.fingard.net.TcpReceiver;
import com.fingard.text.StringHelper;
import com.fingard.util.TransIDHelper;

public class CMB02Base extends DirectBase implements ITcpClient {
	protected String getCharset() {
		return getBankConfig().getCharset("GBK");
	}

	private static TransIDHelper idHelper = new TransIDHelper(1, 999);

	protected String getQryTransID() {
		Date tmpDateNow = new Date();
		return Format.DateTime12Year2Format.format(tmpDateNow) + idHelper.getNextIDStr();
	}

	/**
	 * 密钥交换(生成MacKey)
	 * 
	 * 申请传输密钥(CMDK) -- 获取数据报文密钥的传输密钥 申请数据密钥(CMDM) -- 获取数据传输密钥
	 * 
	 * @return macKey
	 * @throws Exception
	 */
	protected String[] exchangeMacKey() throws Exception {
		String[] tmpStrRet = new String[] {"",""};

		// 1.申请传输密钥
		WriteBankLogLn("开始申请传输密钥(CMDK)...");
		StringBuilder tmpTransKeyReq = new StringBuilder();

		StringBuilder tmpTransKeyBody = new StringBuilder();
		tmpTransKeyBody.append(String.format("%-20s", bankFront.corpNo));

		StringBuilder tmpTransKeyHeader = new StringBuilder();
		tmpTransKeyHeader.append("CMBA");
		tmpTransKeyHeader.append(String.format("%-4s", tmpTransKeyBody.length()));
		tmpTransKeyHeader.append("CMDK");
		tmpTransKeyHeader.append(String.format("%-8s", ""));
		tmpTransKeyHeader.append(String.format("%-6s", ""));
		tmpTransKeyHeader.append(String.format("%-30s", ""));
		Date tmpDateNow = new Date();
		tmpTransKeyHeader.append(Format.Date8Format.format(tmpDateNow));
		tmpTransKeyHeader.append(Format.Time6Format.format(tmpDateNow));
		tmpTransKeyHeader.append(String.format("%-25s", getQryTransID()));
		tmpTransKeyHeader.append("0.2.0");
		tmpTransKeyHeader.append(String.format("%-10s", bankFront.corpNo));
		tmpTransKeyHeader.append(String.format("%-16s", ""));

		tmpTransKeyReq = tmpTransKeyReq.append(tmpTransKeyHeader).append(tmpTransKeyBody);
		WriteBankLogLn("申请传输密钥(CMDK)请求数据:\r\n" + tmpTransKeyReq.toString());

		String[] tmpBankRet = sendToBank(tmpTransKeyReq.toString());
		if (tmpBankRet[0].length() == 0) {
			WriteBankLogLn("申请传输密钥(CMDK)响应数据:\r\n" + tmpBankRet[1]);
			String tmpRespCode = tmpBankRet[1].substring(0, 7);
			if ("CMBMB99".equals(tmpRespCode)) {
				String tmpDeKey = tmpBankRet[1].substring(7, 38).trim();
				WriteBankLogLn("申请传输密钥(CMDK)成功,DeKey值为:" + tmpDeKey);
				
				String saltKey = getBankConfig().getValueAsString("saltKey");
				if (StringHelper.isNullOrEmpty(saltKey)) {
					tmpStrRet[0] = "-1";
					tmpStrRet[1] = "申请传输密钥(CMDK)失败:saltKey为空,请检查config.xml中'saltKey'配置信息";
					return tmpStrRet;
				}
				tmpDeKey = CDesHelper.decrypt(tmpDeKey, saltKey);
				WriteBankLogLn("DeKey解密成功,明文为:" + tmpDeKey);

				// 2.申请数据密钥
				WriteBankLogLn("开始申请数据密钥(CMDM)...");
				StringBuilder tmpDataKeyReq = new StringBuilder();

				StringBuilder tmpDataKeyBody = new StringBuilder();
				tmpDataKeyBody.append(String.format("%-20s", bankFront.corpNo));

				StringBuilder tmpDataKeyHeader = new StringBuilder();
				tmpDataKeyHeader.append("CMBA");
				tmpDataKeyHeader.append(String.format("%-4s", tmpTransKeyBody.length()));
				tmpDataKeyHeader.append("CMDM");
				tmpDataKeyHeader.append(String.format("%-8s", ""));
				tmpDataKeyHeader.append(String.format("%-6s", ""));
				tmpDataKeyHeader.append(String.format("%-30s", ""));
				tmpDataKeyHeader.append(Format.Date8Format.format(tmpDateNow));
				tmpDataKeyHeader.append(Format.Time6Format.format(tmpDateNow));
				tmpDataKeyHeader.append(String.format("%-25s", getQryTransID()));
				tmpDataKeyHeader.append("0.2.0");
				tmpDataKeyHeader.append(String.format("%-10s", bankFront.corpNo));
				tmpDataKeyHeader.append(String.format("%-16s", ""));

				tmpDataKeyReq = tmpDataKeyReq.append(tmpDataKeyHeader).append(tmpDataKeyBody);
				WriteBankLogLn("申请数据密钥(CMDM)请求数据:\r\n" + tmpDataKeyReq.toString());

				tmpBankRet = sendToBank(tmpDataKeyReq.toString());
				if (tmpBankRet[0].length() == 0) {
					WriteBankLogLn("申请数据密钥(CMDM)响应数据:\r\n" + tmpBankRet[1]);
					tmpRespCode = tmpBankRet[1].substring(0, 7);
					if ("CMBMB99".equals(tmpRespCode)) {
						String tmpMacKey = tmpBankRet[1].substring(38, 69).trim();
						WriteBankLogLn("申请数据密钥(CMDM)成功,MacKey密文为:" + tmpMacKey);

						tmpMacKey = CDesHelper.decrypt(tmpMacKey, tmpDeKey);
						WriteBankLogLn("MacKey解密成功,明文为:" + tmpMacKey);

						// 3.将得到的密钥保存至本地
						String tmpMacKeyPath = getCfgDirectory() + File.separator + "macKey";
						FileHelper.writeFile(tmpMacKeyPath, tmpMacKey, getCharset());
						WriteBankLogLn("MacKey明文保存本地成功,路径为:" + tmpMacKeyPath);
					} else {
						WriteBankLogLn(
								"申请数据密钥(CMDM)失败:" + tmpRespCode + "-" + tmpBankRet[1].substring(69, 148).trim());
						tmpStrRet[0] = "-1";
						tmpStrRet[1] = "申请数据密钥(CMDM)失败:" + tmpRespCode + "-" + tmpBankRet[1].substring(69, 148).trim();
					}
				} else {
					WriteBankLogLn("申请数据密钥(CMDM)失败:" + tmpBankRet[1]);
					tmpStrRet[0] = "-1";
					tmpStrRet[1] = "申请数据密钥(CMDM)失败:" + tmpBankRet[1];
				}
			} else {
				WriteBankLogLn("申请传输密钥(CMDK)失败:" + tmpRespCode + "-" + tmpBankRet[1].substring(38, 118).trim());
				tmpStrRet[0] = "-1";
				tmpStrRet[1] = "申请传输密钥(CMDK)失败:" + tmpRespCode + "-" + tmpBankRet[1].substring(38, 118).trim();
			}
		} else {
			WriteBankLogLn("申请传输密钥(CMDK)失败:" + tmpBankRet[1]);
			tmpStrRet[0] = "-1";
			tmpStrRet[1] = "申请传输密钥(CMDK)失败:" + tmpBankRet[1];
		}
		return tmpStrRet;
	}

	protected String[] sendToBank(String p_reqStr) throws Exception {
		String[] retStr = new String[] { "", "" };

		WriteBankLogLn("2.提交银行的地址：" + bankFront.serverIP + ":" + bankFront.serverPort);
		WriteBankLogStep2(p_reqStr);

		TcpPortClient tmpClient = new TcpPortClient(bankFront.serverIP, Integer.parseInt(bankFront.serverPort), this);
		String tmpCharset = getCharset();
		TcpReceiver tmpReceiver = tmpClient.sendMessage(p_reqStr.getBytes());
		/*if (StringHelper.isNullOrEmpty(tmpReceiver.connState)) {
			String tmpBkStr = new String(tmpReceiver.recBytes, 0, tmpReceiver.readedLength, tmpCharset);
			WriteBankLogStep3(tmpBkStr);
		}*/
		retStr[0] = tmpReceiver.connState;
		if (tmpReceiver.isCompleted) {
			retStr[1] = new String(tmpReceiver.recBytes, tmpReceiver.contentStartIndex, tmpReceiver.contentLength,
					tmpCharset);
			WriteBankLogStep3(retStr[1]);
		} else {
			retStr[1] = tmpReceiver.getConnMsg();
			WriteBankLogLn(retStr[1]);
		}
		return retStr;
	}
	
	public void getContentLength(TcpReceiver p_receiver) throws Exception {
        if (p_receiver.contentLength == -1) {
            if (p_receiver.readedLength >= 126) {
                p_receiver.contentLength = Integer.parseInt(new String(p_receiver.recBytes, 4, 4, getCharset()).trim());
                p_receiver.contentStartIndex = 126;
            }
        }
    }

}
